<template>
  <div class="mb-2.5 search-content">
    <div v-if="title" class="font-semibold pb-4.5 text-color-header dark:text-white" :class="titleSizeClass">
      {{ title }}
    </div>
    <a-form layout="inline">
      <a-form-item v-for="el in selectData" :key="el.key" :name="el.key" class="!mb-2">
        <LabelSelect
          v-model:value="innerSearchModel[el.key]"
          v-bind="el.props"
          :is-tree-select="el.isTreeSelect"
          :label="el.label"
          :options="el.options"
          :select-type="el.selectType"
          :container-width="el.containerWidth"
          :size="size"
          @change="onSelectChange(el)"
        />
      </a-form-item>
      <a-form-item v-if="keywordSearchData && keywordSearchData.length > 0" class="!mb-2">
        <a-input-search
          v-model:value="innerKeyword"
          class="xl:!w-72"
          :maxlength="maxlength"
          :placeholder="searchInputTip"
          :size="size"
          @search="handleKeywordSearch"
        >
          <template #enterButton>
            <a-button>
              <template #icon><Icon type="icon-sousuo" /></template>
            </a-button>
          </template>
        </a-input-search>
      </a-form-item>
      <a-form-item v-if="hideSelectData && hideSelectData.length > 0" class="!mb-2">
        <a-dropdown v-model:visible="hideSelectVisible" placement="bottomRight" :trigger="['click']">
          <a-button>
            <template #icon>
              <Icon type="icon-shaixuan" class="!text-color-secondary" />
            </template>
          </a-button>
          <template #overlay>
            <div class="bg-white shadow-md rounded">
              <div class="px-3 py-2 text-color-secondary border-0 border-b border-gray-200 border-solid">
                {{ t("components.searchForm.filterOption") }}
              </div>
              <a-form class="!p-4" layout="vertical" :model="hideSearchModel">
                <a-form-item v-for="el in hideSelectData" :key="el.key" :name="el.key">
                  <template #label>
                    <span class="text-sl-color-2">{{ el.label }}</span>
                  </template>
                  <a-select v-model:value="hideSearchModel[el.key]" class="!w-64" :options="el.options"> </a-select>
                </a-form-item>
                <a-form-item class="text-right !mb-0">
                  <a-button @click="resetHideSelect">{{ t("common.reset") }}</a-button>
                  <a-button type="primary" class="ml-3" @click="hideSelectSearch">{{ t("common.ok") }}</a-button>
                </a-form-item>
              </a-form>
            </div>
          </template>
        </a-dropdown>
      </a-form-item>
      <a-form-item v-if="innerColumns && innerColumns.length > 0 && requiredKeys" class="!mb-2">
        <ColumnFilter v-model:columns="innerColumns" :required-keys="requiredKeys" :size="size" />
      </a-form-item>
      <div
        v-if="selectData || keywordSearchData || hideSelectData || (innerColumns && requiredKeys)"
        class="!flex-1 !hidden sm:!flex"
      ></div>
      <div class="mb-2">
        <slot name="extraButtons" />
        <PermissionBtn
          v-if="delBtnProps"
          :permission-code="delBtnPermissionCode"
          :oper-type="delBtnOperType"
          :class="{ 'mr-4.5': showAddBtn }"
          :disabled-mes="delBtnDisabledMes"
          :route-name="btnRouteName"
          :btn-props="
            Object.assign(
              {
                danger: true,
                type: 'primary',
                size,
              },
              delBtnProps
            )
          "
          @click="$emit('delete', $event)"
        >
          {{ delBtnText }}
          <template #icon>
            <Icon type="icon-shanchu" />
          </template>
        </PermissionBtn>
        <PermissionBtn
          v-show="showAddBtn"
          :permission-code="addBtnPermissionCode"
          :oper-type="addBtnOperType"
          :route-name="btnRouteName"
          :btn-props="{
            type: 'primary',
            disabled: addBtnDisabled,
            loading: addBtnLoading,
            size,
          }"
          @click="$emit('add', $event)"
        >
          {{ addBtnText }}
          <template #icon>
            <Icon type="icon-tianjia" />
          </template>
        </PermissionBtn>
      </div>
      <slot />
    </a-form>
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, useSlots, inject } from "vue";
import { Form } from "ant-design-vue";
import type { ButtonProps, TableColumnProps } from "ant-design-vue";
import Icon from "/@/components/Icon.vue";
import ColumnFilter from "/@/components/ColumnFilter.vue";
import { useI18n } from "/@/locales/useI18n";
import {
  KeywordSearchItem,
  LabelSelectType,
  SearchFormExpose,
  SearchFormKeywordKey,
  SelectItem,
} from "/@/types/components";
import PermissionBtn from "/@/components/PermissionBtn.vue";
import type { TableRecord } from "/@/api/models";
import { PermissionCode } from "/@/api/permissionCode";
import { OperPermissionType } from "/@/api/aiot/role/models";
const props = withDefaults(
  defineProps<{
    title?: string;
    titleSizeClass?: string;
    selectData?: SelectItem[];
    keyword?: string;
    keywordSearchData?: (string | KeywordSearchItem)[];
    hideSelectData?: SelectItem[];
    columns?: TableColumnProps<TableRecord>[];
    requiredKeys?: string[];
    addBtnText?: string;
    addBtnDisabled?: boolean;
    addBtnLoading?: boolean;
    addBtnPermissionCode?: PermissionCode;
    addBtnOperType?: OperPermissionType;
    showAddBtn?: boolean;
    delBtnText?: string;
    delBtnProps?: ButtonProps;
    delBtnPermissionCode?: PermissionCode;
    delBtnOperType?: OperPermissionType;
    delBtnDisabledMes?: string | null;
    btnRouteName?: string;
    size?: ButtonProps["size"];
    maxlength?: number;
    partSearchModel?: Record<string, any>;
  }>(),
  {
    showAddBtn: true,
    keyword: "",
    maxlength: 32,
    titleSizeClass: "text-2xl",
  }
);
const emits = defineEmits(["update:columns", "add", "search", "update:keyword", "delete"]);
const { t } = useI18n();
//所有值对象
function isDateSelect(item: SelectItem) {
  return item.selectType === LabelSelectType.datePicker || item.selectType === LabelSelectType.rangePicker;
}
let innerSearchModel = {};
function search() {
  const model = { ...innerSearchModel };
  emits("search", model);
}
//前置条件select筛选
function initSelectValue() {
  props.selectData?.forEach((item) => {
    if (isDateSelect(item)) {
      innerSearchModel[item.key] = item.value || null;
    } else {
      innerSearchModel[item.key] = item.value || "";
    }
  });
}
function onSelectChange(el: SelectItem) {
  // if (isDateSelect(el)) {
  //   // datePicker rangPicker 不自动触发search
  //   return;
  // }
  // search();
  handleKeywordSearch();
}
initSelectValue();
watch(
  () => props.selectData,
  () => {
    initSelectValue();
  },
  {
    deep: true,
  }
);
//关键字模糊搜索
const searchInputTip = ref("");
const keywordModel = {};
if (props.keywordSearchData) {
  const columns = props.columns;
  const searchTip: string[] = [];
  props.keywordSearchData.forEach((item) => {
    let key = "",
      label = "";
    if (typeof item === "string") {
      if (columns) {
        //对某一列字段模糊搜索
        key = item;
        for (let i = 0, ii = columns.length; i < ii; i++) {
          const column = columns[i];
          if (column.dataIndex === key) {
            label = column.title as string;
            break;
          }
        }
      } else {
        console.warn("请传入列表columns对象");
      }
    } else {
      //对多列字段模糊搜索
      key = item.key;
      label = item.label;
    }
    if (key) {
      searchTip.push(label);
      keywordModel[key] = "";
      innerSearchModel[key] = "";
    }
  });
  searchInputTip.value = t("components.searchForm.plzInputSearchTip", {
    text: searchTip.join(t("components.searchForm.or")),
  });
}
const innerKeyword = ref("");
function handleKeywordSearch() {
  for (let i in keywordModel) {
    keywordModel[i] = innerKeyword.value.replace(/\s+/g, "");
  }
  Object.assign(innerSearchModel, keywordModel);
  search();
}
const injectKeyword = inject(SearchFormKeywordKey, null);
if (injectKeyword) {
  watch(injectKeyword, (v) => {
    innerKeyword.value = v || "";
  });
}
watch(
  () => props.keyword,
  (v) => {
    innerKeyword.value = v || "";
  }
);
watch(innerKeyword, (v) => {
  emits("update:keyword", v);
  if (injectKeyword) {
    injectKeyword.value = v;
  }
});
//隐藏条件select筛选
let hideSearchModel = {};
const hideSelectVisible = ref(false);
props.hideSelectData?.forEach((item) => {
  hideSearchModel[item.key] = "";
  innerSearchModel[item.key] = "";
});
function hideSelectSearch() {
  if (props.hideSelectData) {
    props.hideSelectData.forEach((item) => {
      innerSearchModel[item.key] = hideSearchModel[item.key];
    });
  }
  search();
  hideSelectVisible.value = false;
}
innerSearchModel = reactive(innerSearchModel);
hideSearchModel = reactive(hideSearchModel);
watch(
  () => props.partSearchModel,
  (model) => {
    if (model) {
      Object.assign(innerSearchModel, model);
    }
  }
);
const { resetFields: resetHideSelect } = Form.useForm(hideSearchModel, []);
//ColumnFilter组件
let innerColumns: any = null;
if (props.columns) {
  innerColumns = ref([...props.columns]);
  watch(innerColumns, (v) => {
    emits("update:columns", v);
  });
}

const myExpose: SearchFormExpose = {
  clearKeyword() {
    innerKeyword.value = "";
  },
};
defineExpose(myExpose);
</script>
<style lang="less">
.search-content {
  .ant-form-item-control-input {
    min-height: auto;
  }
}
</style>
